use actix_web::{get, web, App, HttpServer, Responder};
use dotenv::dotenv;
use sqlx::MySqlPool;
use std::env;

struct QueryResult {
    field_1: Option<i32>,
}

#[get("/hello")]
async fn index(pool: web::Data<MySqlPool>) -> impl Responder {
    // 将结构体和sql语句进行映射
    if let Ok(v) = sqlx::query_as!(QueryResult, "select field_1 from test_table")
        // 在Actix-web框架里, 获取App data必须是基于Arc<原子性>并且是线程安全的
        // 所以只能通过get_ref来获取
        // 直接通过&pool的行为是不安全的
        .fetch_one(pool.get_ref())
        .await
    {
        // 通过结构体的字段来获取值, 并直接返回该response
        if let Some(v) = v.field_1 {
            return format!("{}", v);
        }
    }

    format!("没有查询到数据")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("没有从环境变量中获得数据库地址");

    let pool = MySqlPool::connect(&database_url).await.unwrap();

    HttpServer::new(move || App::new().data(pool.clone()).service(index))
        .bind("127.0.0.1:8080")?
        .run()
        .await?;

    Ok(())
}
